package webport_web

import (
	"context"
	"fmt"
	"net/http"
	"os"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
)

var WebServerHost = "localhost"
var WebServerPort = 12500

type WebServer struct {
	httpServer *http.Server
}

func NewWebServer() *WebServer {
	return &WebServer{}
}

func (s *WebServer) Start() {
	go s.run()
}

func (s *WebServer) run() {
	// gin.Default 会自动使用 Logger 和 Recovery 中间件
	ginApp := gin.Default()

	corsConfig := cors.DefaultConfig()
	corsConfig.AllowAllOrigins = true
	// - AllowMethods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
	// - AllowHeaders: Origin, Content-Length, Content-Type
	// - AllowCredentials: false, credentials share disabled
	// - MaxAge: 12 * time.Hour, Preflight requests cached for 12 hours
	ginApp.Use(cors.New(corsConfig))

	ginApp.GET("/api/test/ping", handleTestPing)
	ginApp.GET("/api/test/echo", handleTestEcho)
	ginApp.GET("/api/test/sleep", handleTestSleep)

	ginApp.GET("/api/status/online", handleStatusOnline)

	ginApp.GET("/api/control/stop", handleControlStop)
	ginApp.GET("/api/control/restart", handleControlRestart)

	ginApp.GET("/api/system/type", handleSystemType)
	ginApp.GET("/api/system/cpu_count", handleSystemCPUCount)
	ginApp.GET("/api/system/user", handleSystemUser)
	ginApp.GET("/api/system/user_home", handleSystemUserHome)
	ginApp.GET("/api/system/time/unix", handleSystemTimeUnix)
	ginApp.GET("/api/system/time/zone", handleSystemTimeZone)
	ginApp.GET("/api/system/time/local", handleSystemTimeLocal)
	ginApp.GET("/api/system/env/:name", handleSystemEnv)
	ginApp.GET("/api/system/net/ip", handleSystemNetIP)

	ginApp.GET("/api/windows/registry", handleWindowsRegistry)

	ginApp.GET("/api/fs/cwd", handleFsCwd)
	ginApp.GET("/api/fs/exe", handleFsExe)
	ginApp.GET("/api/fs/stat", handleFsStat)
	ginApp.GET("/api/fs/exists", handleFsExists)
	ginApp.GET("/api/fs/is_dir", handleFsIsDir)
	ginApp.GET("/api/fs/is_file", handleFsIsFile)
	ginApp.POST("/api/fs/chmod", handleFsChmod)
	ginApp.POST("/api/fs/rename", handleFsRename)
	ginApp.GET("/api/fs/list_dir", handleFsListDir)
	ginApp.POST("/api/fs/make_dir", handleFsMakeDir)
	ginApp.POST("/api/fs/remove_dir", handleFsRemoveDir)
	ginApp.GET("/api/fs/read_file", handleFsReadFile)
	ginApp.POST("/api/fs/write_file", handleFsWriteFile)
	ginApp.POST("/api/fs/write_file_chunk", handleFsWriteFileChunk)
	ginApp.POST("/api/fs/append_file", handleFsAppendFile)
	ginApp.POST("/api/fs/remove_file", handleFsRemoveFile)

	ginApp.POST("/api/shell/open_file", handleShellOpenFile)
	ginApp.POST("/api/shell/exec_file", handleShellExecFile)
	ginApp.POST("/api/shell/exec_cmd", handleShellExecCmd)
	ginApp.GET("/api/shell/find_cmd", handleShellFindCmd)

	ginApp.GET("/api/ws/test/echo", handleWsTestEcho)
	ginApp.GET("/api/ws/shell/exec_file", handleWsShellExecFile)

	listenAddr := fmt.Sprintf("%s:%d", WebServerHost, WebServerPort)

	s.httpServer = &http.Server{
		Addr:    listenAddr,
		Handler: ginApp,
	}

	err := s.httpServer.ListenAndServe()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: cannot start web server: %s\n", err)
		os.Exit(1)
	}
}

func (s *WebServer) Stop() {
	s.httpServer.Shutdown(context.Background())
}
